package cn.kgc.itrip.trade.controller;

import cn.kgc.itrip.beans.dto.Dto;
import cn.kgc.itrip.beans.pojo.ItripHotelOrder;
import cn.kgc.itrip.trade.service.HotelOrderService;
import cn.kgc.itrip.trade.utils.MyConfig;
import cn.kgc.itrip.trade.utils.WXPay;
import cn.kgc.itrip.trade.utils.WXPayConstants;
import cn.kgc.itrip.trade.utils.WXPayUtil;
import cn.kgc.itrip.utils.DtoUtil;
import cn.kgc.itrip.utils.EmptyUtils;
import cn.kgc.itrip.utils.ErrorCode;
import lombok.Cleanup;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping("/api/wxpay")
public class WxPayController {

    @Resource
    private MyConfig myConfig;
    @Resource
    private HotelOrderService hotelOrderService;

    /**
     * 微信支付页面-订单状态查询
     */
    @ResponseBody
    @RequestMapping(value = "/queryorderstatus/{orderNo}",method = RequestMethod.GET)
    public Dto doQueryOrderStatus(@PathVariable String orderNo){
        try {
            ItripHotelOrder itripHotelOrder = hotelOrderService.getOrderByOrderNo(orderNo);
            return DtoUtil.returnDataSuccess(itripHotelOrder);
        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail("查询订单状态失败！",ErrorCode.TRADE_UNKNOWN);
        }
    }

    /**
     * 微信支付-支付结果通知
     */
    @RequestMapping(value = "/notify",method = RequestMethod.POST)
    public void doNotify(HttpServletRequest request, HttpServletResponse response){
        try {
            // 接收数据流信息
            @Cleanup ServletInputStream is = request.getInputStream();
            // 定义Buffer存储数据流字符串
            StringBuffer notifyBuffer = new StringBuffer();
            byte[] bytes = new byte[1024];
            int len = 0;
            while((len = is.read(bytes)) != -1){
                notifyBuffer.append(new String(bytes,0,len));
            }
            // 将数据流字符串转换为map集合
            Map<String, String> notifyMap = WXPayUtil.xmlToMap(notifyBuffer.toString());
            WXPay wxpay = new WXPay(myConfig);
            // 签名验证
            if(wxpay.isPayResultNotifySignatureValid(notifyMap)){
                // 验证是否交易成功
                if(notifyMap.get("return_code").equals(WXPayConstants.SUCCESS)
                        && notifyMap.get("result_code").equals(WXPayConstants.SUCCESS)){
                    if(hotelOrderService.checkOrderStatus(notifyMap)){
                        //更改订单状态
                        hotelOrderService.updateOrder(notifyMap);
                    }
                }
            }
            Map<String,String> resultMap = new HashMap<>();
            resultMap.put("return_code",WXPayConstants.SUCCESS);
            resultMap.put("return_msg","OK");
            response.getWriter().print(WXPayUtil.mapToXml(resultMap));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 微信支付-生成预支付交易单(二维码)
     */
    @ResponseBody
    @RequestMapping(value = "/createqccode/{orderNo}",method = RequestMethod.GET)
    public Dto doCreateQcCode(@PathVariable String orderNo, HttpServletRequest request){
        try {
            ItripHotelOrder itripHotelOrder = hotelOrderService.getOrderByOrderNo(orderNo);
            // 验证订单是否存在
            if(EmptyUtils.isEmpty(itripHotelOrder)){
                return DtoUtil.returnFail("订单不存在！",ErrorCode.TRADE_PARAMETER_ERROR);
            }
            // 验证订单是否已经结束
            if(itripHotelOrder.getOrderStatus() != 0){
                return DtoUtil.returnFail("订单已经结束！",ErrorCode.TRADE_ORDER_ALREADY_OVER);
            }

            WXPay wxpay = new WXPay(myConfig);
            Map<String, String> data = new HashMap<String, String>();
            data.put("body", "爱旅行-酒店支付");
            data.put("out_trade_no", orderNo);
            // 设备号 自定义参数，可以为终端设备号(门店号或收银设备ID)，PC网页或公众号内支付可以传"WEB"
            data.put("device_info", "WEB");
            data.put("total_fee", "1");
            // 终端IP 支持IPV4和IPV6两种格式的IP地址。用户的客户端IP
            data.put("spbill_create_ip", request.getRemoteAddr());
            data.put("notify_url", "http://266v6a9928.wicp.vip/trade/api/wxpay/notify");
			// 此处指定为扫码支付
            data.put("trade_type", "NATIVE");  
            data.put("product_id", itripHotelOrder.getRoomId()+"");
            // 签名类型，默认为MD5，支持HMAC-SHA256和MD5。
            data.put("sign_type", WXPayConstants.HMACSHA256);
            // 发起统一下单请求
            Map<String, String> resp = wxpay.unifiedOrder(data);
            // 结果需要返回总金额  和  二维码链接
            Map<String,Object> result = new HashMap<>();
            if(resp.get("return_code").equals(WXPayConstants.SUCCESS)
                    && resp.get("result_code").equals(WXPayConstants.SUCCESS)){
                //  二维码链接 trade_type=NATIVE时有返回，此url用于生成支付二维码，然后提供给用户进行扫码支付。
                result.put("codeUrl",resp.get("code_url"));
                result.put("payAmount",itripHotelOrder.getPayAmount());
                return DtoUtil.returnDataSuccess(result);
            }else{
                // 失败
                return DtoUtil.returnFail(resp.get("retrun_msg"),ErrorCode.TRADE_RESULT_ERROR);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return DtoUtil.returnFail("获取支付二维码失败！", ErrorCode.TRADE_UNKNOWN);
        }
    }

}


